﻿using FlowDesigner.Flow;
using FlowDesigner.HelperVision;
using FlowDesigner.Models;
using FlowDesigner.ViewModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace FlowDesigner
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑 节目回头着不妨不好放在ViewModel里 逻辑就在这里写吧
    /// </summary>
    public partial class MainWindow : Window
    {
        //public List<FloWTask> ProcessNodeList { get; set; } = new List<FloWTask>();
        //private Dictionary<string,string> iconfontlist = new Dictionary<string,string>();
        private NodeS floWTaskStat;
        private NodeS floWTaskend;
        private bool IsPress=false;
        private bool Islinkopen=false;
        //public static HelperVision.EventAggregator1 eventAggregator = new HelperVision.EventAggregator1();
        //控制曲线绘制的坐标
        private Point _startPoint;
        private Point _endPoint;
        private Line line_;
        private Line arrowhead1;
        private Line arrowhead2;
        //测试连接线颜色
        SolidColorBrush solidColorBrush2 ;
        private MainViewModel mainViewModel;
        /// <summary>
        /// 
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
            mainViewModel = new MainViewModel();
            this.DataContext = mainViewModel;
            //eventAggregator.Subscribe<string>(Mouseitemcont);
        }      
        // 放置操作，处理 Drop 事件 
        private void Canvas_Drop(object sender, DragEventArgs e)
        {
            // 获取拖动的数据
            if (e.Data.GetDataPresent("ButtonContent"))
            {
                   string buttonContent = e.Data.GetData("ButtonContent") as string;
                    // 获取鼠标放置的位置
                    Point dropPosition = e.GetPosition(dragCanvas);
                   if(mainViewModel.ProcessNodeList.Any(o=>string.Equals(o.Tag,"起始"))&&string.Equals(buttonContent, "起始"))
                    {
                    MessageBox.Show("起始节点必须唯一");
                    return;
                    }
                    if(mainViewModel.ProcessNodeList.Any(o => string.Equals(o.Tag, "结束"))&& string.Equals(buttonContent, "结束"))
                    {
                    MessageBox.Show("结束必须唯一");
                    return;
                    }
                 //流程信息
                FloWTask floWTask = new FloWTask()
                {
                    Tag = buttonContent,
                    flowIndex = mainViewModel.ProcessNodeList.Any() ? mainViewModel.ProcessNodeList.Max(o => o.flowIndex) + 1 : 1,
                    X= dropPosition.X, 
                    Y= dropPosition.Y,
                    Startnode= string.Equals(buttonContent, "起始") ? true: false
                };
                //用户展示
                NodeS nodeS = new NodeS()
                {
                    strFont = mainViewModel.iconfontlist[buttonContent],
                    Width = 100,
                    Height = 100,
                    Tag = buttonContent,
                    Foreground = string.Equals(buttonContent, "结束") ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Color.FromArgb(255, 0, 150, 242)),
                    staPoint = dropPosition,
                    ParentItemsControl= floWTask                 
                };
                if(string.Equals(buttonContent, "结束")==false)
                {
                    ContextMenu contextMenu = new ContextMenu();
                    contextMenu.SetResourceReference(MenuItem.StyleProperty, "ContextMenusty"); // 从资源中应用样式;
                    nodeS.ContextMenu = contextMenu;
                    // 添加 MenuItem
                    MenuItem menuItem1 = new MenuItem { Header = "删除" };
                    menuItem1.SetBinding(MenuItem.CommandProperty, new Binding("Deletecommand"));// 绑定命令
                    //contextMenu.SetResourceReference(MenuItem.StyleProperty, "MenuItemsty"); // 从资源中应用样式;                                                                    //menuItem1.SetBinding(MenuItem.CommandParameterProperty, new Binding()
                                                                                                //{
                                                                                                //    RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(NodeS), 1) // 绑定参数 有问题
                                                                                                //});
                    menuItem1.CommandParameter = nodeS;
                    MenuItem menuItem2 = new MenuItem { Header = "编辑" };
                    menuItem2.SetBinding(MenuItem.CommandProperty, new Binding("Editcommand"));// 绑定命令
                    //contextMenu.SetResourceReference(MenuItem.StyleProperty, "MenuItemsty"); // 从资源中应用样式;                                                                  //menuItem2.SetBinding(MenuItem.CommandParameterProperty, new Binding()
                                                                                                //{
                                                                                                //    RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(NodeS), 1) // 绑定参数
                                                                                                //});    
                    menuItem2.CommandParameter = nodeS;
                    contextMenu.Items.Add(menuItem1);
                    contextMenu.Items.Add(menuItem2);
                }                
                //添加节点信息
                mainViewModel.ProcessNodeList.Add(floWTask);
                // 设置控件的附加属性来定位
                Canvas.SetLeft(nodeS, dropPosition.X - 50); // 水平位置
                Canvas.SetTop(nodeS, dropPosition.Y - 50);  // 垂直位置
                dragCanvas.Children.Add(nodeS);
            }
        }

        private void dragCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            e.Handled = true;
            if (IsPress)
            {
                if (floWTaskStat.ParentItemsControl.NexflowIndex != 0&& floWTaskStat.ParentItemsControl.Branch==false)
                {
                    IsPress = false;
                    MessageBox.Show("此节点不是分支节点不能重复链接!"); // 鼠标点击事件
                    return;
                }
                var itemcont = sender as Canvas;
                _endPoint = e.GetPosition(itemcont);
                DrawBezierCurve(line_,_startPoint,_endPoint);
            }
        }
        private void dragCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!Islinkopen) return;
            _startPoint = e.GetPosition(sender as Canvas);
            HitTestResult hitTestResult = VisualTreeHelper.HitTest(sender as Canvas, _startPoint);
            if (hitTestResult?.VisualHit!=null)
            {
              var node= VisuaXml.FindParentNodeS(hitTestResult.VisualHit);
                if (node!=null)
                {
                    floWTaskStat = node;
                    line_ = new Line();
                    dragCanvas.Children.Add(line_);
                    line_.Stroke = mainViewModel.solidColorBrush;
                    line_.StrokeThickness = 2;
                    IsPress = true;
                }
            }
        }
        private void dragCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            e.Handled= true;
            IsPress = false;
            if (!Islinkopen) return;
            var itemcont = sender as Canvas;
            Point mousePosition = e.GetPosition(itemcont);
            HitTestResult hitTestResult = VisualTreeHelper.HitTest(itemcont, mousePosition);
            if (hitTestResult?.VisualHit != null)
            {
                var node = VisuaXml.GetElementAt<NodeS>(itemcont, mousePosition.X,mousePosition.Y);
                if(node!=null&&floWTaskStat.ParentItemsControl.Branch&& floWTaskStat.ParentItemsControl.NexflowIndexBranch.Contains(node.ParentItemsControl.flowIndex))
                {
                    dragCanvas.Children.Remove(line_);
                    return;
                }
                if(node==null&&line_!=null||object.ReferenceEquals(node,floWTaskStat))
                {
                     dragCanvas.Children.Remove(line_); 
                }
                else
                {
                    if (Math.Abs(_endPoint.X - _startPoint.X) < 20) return;//防止鼠标双击移动产生的影响
                    floWTaskend=node;
                    //绘制箭头
                    arrowhead1 = new Line();
                    arrowhead1.Stroke = mainViewModel.solidColorBrush;
                    arrowhead1.StrokeThickness = 2;
                    arrowhead2 = new Line();
                    arrowhead2.Stroke = mainViewModel.solidColorBrush;
                    arrowhead2.StrokeThickness = 2;
                    DrawArrow(arrowhead1, arrowhead2, _startPoint, _endPoint
                    );

                    //添加到面板中
                    dragCanvas.Children.Add(arrowhead1);
                    dragCanvas.Children.Add(arrowhead2);
                    //添加鼠标移动事件
                    line_.MouseEnter += Line_MouseEnter;
                    line_.MouseLeave += Line_MouseLeave;
                    line_.MouseDown += Line_MouseDown;
                    // 保存连接线坐标
                    node.ParentItemsControl.X = line_.X1;
                    node.ParentItemsControl.Y = line_.Y1;
                    node.ParentItemsControl.X1 = line_.X2;
                    node.ParentItemsControl.Y1 = line_.Y2;
                    //找到链接下一个节点
                    if (floWTaskStat.ParentItemsControl.Branch)
                    {
                        floWTaskStat.ParentItemsControl.flowIndex = -1;//设置为分支节点
                        floWTaskStat.ParentItemsControl.NexflowIndexBranch.Add(floWTaskStat.ParentItemsControl.flowIndex);
                        mainViewModel.ProcessNodeList.Single(o => o.flowIndex == floWTaskStat.ParentItemsControl.flowIndex).NexflowIndexBranch.Add(floWTaskStat.ParentItemsControl.flowIndex);
                    }
                    else
                    {
                        floWTaskStat.ParentItemsControl.NexflowIndex = floWTaskend.ParentItemsControl.flowIndex;
                        mainViewModel.ProcessNodeList.Single(o => o.flowIndex == floWTaskStat.ParentItemsControl.flowIndex).NexflowIndex = node.ParentItemsControl.flowIndex;
                    }
                   
                }
            }
        }
        // 鼠标进入时改变颜色
        private void Line_MouseEnter(object sender, MouseEventArgs e)
        {
            e.Handled = true;
            (sender as Line).Stroke = mainViewModel.solidColorBrush1;
        }

        // 鼠标离开时还原颜色
        private void Line_MouseLeave(object sender, MouseEventArgs e)
        {
            e.Handled = true;
            (sender as Line).Stroke = mainViewModel.solidColorBrush;
        }
        Line line1 = null;
        // 鼠标按下时显示上下文菜单
        private void Line_MouseDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            line1 = sender as Line;

            ContextMenu contextMenu = new ContextMenu();
            contextMenu.SetResourceReference(MenuItem.StyleProperty, "ContextMenusty");

            // 添加菜单项
            MenuItem menuItem1 = new MenuItem { Header = "删除" };
            menuItem1.Click += MenuItem1_Click;

            contextMenu.Items.Add(menuItem1);
            line1.ContextMenu = contextMenu;
            //打开上下文菜单
            contextMenu.IsOpen = true;
        }

        private void MenuItem1_Click(object sender, RoutedEventArgs e)
        {
           var listui=VisuaXml.GetElementAllLineornodes(dragCanvas,line1.X2,line1.Y2);
            foreach (var item in listui)
            {
                if(item  is Line)
                {
                dragCanvas.Children.Remove(item as Line);
                }
            }
            dragCanvas.Children.Remove(line1);
            var NodeSlist_= VisuaXml.GetElementAt<NodeS>(dragCanvas,line1.X1,line1.Y1);//起始节点
            if (NodeSlist_ == null)
            {
                System.Windows.Forms.MessageBox.Show("删除链接失败!");//
            }
            if (NodeSlist_.ParentItemsControl.Branch)
            {
                var NodeSlistend = VisuaXml.GetElementAt<NodeS>(dragCanvas, line1.X2, line1.Y2);//起始节点
                if (NodeSlistend == null)
                {
                    System.Windows.Forms.MessageBox.Show("删除链接失败!");//
                }
                NodeSlist_.ParentItemsControl.NexflowIndexBranch.Remove(NodeSlistend.ParentItemsControl.flowIndex);
            }
            else
            {
                NodeSlist_.ParentItemsControl.NexflowIndex = 0;//清除链接
            }
            line1.MouseEnter += Line_MouseEnter;
            line1.MouseLeave += Line_MouseLeave;
            line1.MouseDown += Line_MouseDown;
        }

        // 绘制直线
        private void DrawBezierCurve(Line path, Point _startPoint, Point _endPoint)
        {
            if(_startPoint==null|| _endPoint==null)return;
            path.X1 =  _startPoint.X;
            path.Y1 =  _startPoint.Y;
            path.X2 =  _endPoint.X;
            path.Y2 =  _endPoint.Y;
        }
        /// <summary>
        /// 绘制带箭头的直线
        /// </summary>
        /// <param name="canvas">绘制的 Canvas</param>
        /// <param name="start">直线的起点</param>
        /// <param name="end">直线的终点</param>
        /// <param name="arrowLength">箭头的长度</param>
        /// <param name="arrowAngle">箭头与直线的夹角（单位：度）</param>
        public void DrawArrow(Line arrowLine1,Line arrowLine2, Point start, Point end, double arrowLength = 20, double arrowAngle = 30)
        {
            // 计算直线的角度（弧度）
            double angle = Math.Atan2(end.Y - start.Y, end.X - start.X);
            // 算出箭头的两条线段的角度
            double angle1 = angle + arrowAngle * Math.PI / 180; // 顺时针方向
            double angle2 = angle - arrowAngle * Math.PI / 180; // 逆时针方向
            // 算出箭头两端点
            Point arrowPoint1 = new Point(
                end.X - arrowLength * Math.Cos(angle1),
                end.Y - arrowLength * Math.Sin(angle1)
            );
            Point arrowPoint2 = new Point(
                end.X - arrowLength * Math.Cos(angle2),
                end.Y - arrowLength * Math.Sin(angle2)
            );
            arrowLine1.X1 = end.X;
            arrowLine1.Y1 = end.Y;
            arrowLine1.Y2 = arrowPoint1.Y;
            arrowLine1.X2 = arrowPoint1.X;
            arrowLine2.X1 = end.X;
            arrowLine2.Y1 = end.Y;
            arrowLine2.X2 = arrowPoint2.X;
            arrowLine2.Y2 = arrowPoint2.Y;
        }
        /// <summary>
        /// 添加连接事件
        /// </summary>
        private void Addlink()
        {
            dragCanvas.MouseLeftButtonUp += dragCanvas_MouseLeftButtonUp;
            dragCanvas.MouseLeftButtonDown += dragCanvas_MouseLeftButtonDown;
            dragCanvas.MouseMove += dragCanvas_MouseMove;

        }
        /// <summary>
        /// 移除连接事件
        /// </summary>
        private void Removelink()
        {
            dragCanvas.MouseLeftButtonUp -= dragCanvas_MouseLeftButtonUp;
            dragCanvas.MouseLeftButtonDown -= dragCanvas_MouseLeftButtonDown;
            dragCanvas.MouseMove -= dragCanvas_MouseMove;

        }
        /// <summary>
        /// 开始连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lik_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            if (dragCanvas.Children.Count < 3)
            {
                MessageBox.Show("节点必须大于3个");
                return;
            }
            var button = sender as linkNode;
            button.IsOpenLink = !button.IsOpenLink;
            if (button.IsOpenLink)
            {
                var df= VisuaXml.FindLogicalChildren<NodeS>(dragCanvas,new List<NodeS>());
                foreach (var item in df)
                {
                    item.MouseMove -= item.NodeS_MouseMove;
                    item.MouseLeftButtonDown -= item.NodeS_MouseLeftButtonDown;
                    item.MouseLeftButtonUp -= item.NodeS_MouseLeftButtonUp;
                    item.MouseLeave -= item.NodeS_MouseLeave; 
                }
                button.Tag = "正在链接";
                dragCanvas.AllowDrop=false;
                Islinkopen= true;
                Addlink();
            }
            else
            {
                var df = VisuaXml.FindLogicalChildren<NodeS>(dragCanvas, new List<NodeS>());
                foreach (var item in df)
                {
                    item.MouseMove += item.NodeS_MouseMove;
                    item.MouseLeftButtonDown += item.NodeS_MouseLeftButtonDown;
                    item.MouseLeftButtonUp += item.NodeS_MouseLeftButtonUp;
                    item.MouseLeave += item.NodeS_MouseLeave;
                }
                button.Tag = "链接";
                dragCanvas.AllowDrop = true;
                Islinkopen=false;
                Removelink();   
            }
        }
    }
}
